let _Vue;
export default class VueRouter{
    /**
     * 提供一个install 方法，Vue.use的时候会自动调用这个方法
     * @param {Vue实例} Vue 
     */
    static install(Vue){
        // 判断一下插件是不是已经安装过
        if(VueRouter.install.installed){
            return;
        }
        VueRouter.install.installed = true;
        _Vue = Vue;
        // 让所有的Vue组建都能使用vue-router，所以用Mixin
        Vue.mixin({
            beforeCreate(){
                if(this.$options.router){
                    Vue.prototype.$router = this.$options.router;
                    // 挂载组件和解析路由规则---为什么放在这调用而不是在构造函数调用。大概是为了节约资源。如果不使用，这些操作就不用做了
                    this.$options.router.init();
                }
            }
        })
    }
    // 构造函数
    constructor(options){
        // 这里放的是newVueRouter时候传的对象
        this.$options = options;
        // 存储路由解析后的结果，如:{'/':Home}
        this.routerMap = {};
        // data 中current记录当前地址，并且是响应式的--为什么响应式？因为路由变化要更新视图
        this.data = _Vue.observable({
            current:'/' 
        })
    }

    /**
     * 解析路由规则
     */
    createRouterMap(){
        this.$options.routes.forEach(route=>{
            this.routerMap[route.path] = route.component;
        })
    }
    /**
     * 初始化routeView和routeLink
     */
    initComponents(Vue){
        const _that = this;
        Vue.component('router-link',{
            // 这里不能采用template的方式，因为运行时的Vue版本（分为完成版和运行时版本。完整版带有编译器，所以比较大），不支持template的编译。
            // You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
            // 模拟的history模式
            // template:`<a :href="to"><slot></slot></a>`,
            render(h){
                // h 是一个函数，可以帮我们渲染
                return h('a',{
                    attrs:{
                        href:this.to,
                    },
                    on:{
                        click: this.clickHandler
                    }
                },[this.$slots.default])
            },
            methods:{
                clickHandler(e){
                    // 修改vuerouter 实例当中的 current 的值
                    // 但是点击A标签，默认会向服务器发送请求，结果服务器返回的还是index所以切换的话，会导致切换页面马上又回到首页，所以我们要阻止a标签的默认行为
                    e.preventDefault();
                    // 并且还要修改地址。否则因为阻止默认行为，地址没有改变
                    history.pushState({},'',this.to); // 跳转地址，并且不请求服务器
                    this.$router.data.current = this.to;
                }
            },
            props:{
                to:String,
            }
        })
        // 注册routeView
        Vue.component('router-view',{
            render(h){
                // 找到路径对应的组件，进行渲染
                const comp = _that.routerMap[_that.data.current]
                return h(comp);
            }
        })
    }
    initEvent(){
        window.addEventListener('popstate',(e)=>{
            // 浏览器历史记录前进或者后退的时候都会触发这个事件
            console.log('----路由发生了变化----');
            this.data.current = window.location.pathname;
        })
    }
    init(){
        this.createRouterMap();
        this.initComponents(_Vue);
        this.initEvent();
    }
}